var CCAsync = function(){
    this.arrays = null;
}

CCAsync.prototype.parallel = function(arr,func){
    if(this.arrays!=null){
        assert('不允许再次使用')
        return
    }
    if(arr.length == 0){
      return func(null,null);
    }
    
    this.isOver = false
    this.arrays = arr;
    this.callback = func;
    this.results = [];
    try{
        for(let i=0; i<arr.length; i++){
            this.results.push(null);
            var func = arr[i];
            func(this._parallelOver.bind(this,i));
        }
    }catch(e){
        this._parallelOver(i,e,null)
    }
}

CCAsync.prototype._parallelOver = function(i,err,res){
    if(this.isOver){
        return;
    }

    if(err){
        this.isOver = true;
        this.callback(err,this.results);
    } else {
        this.results[i] = res;
        for(var j=0; j<this.arrays.length; j++){
            if(this.results[j] == null){
                return;
            }
        }
        this.isOver = true;
        this.callback(null,this.results);
    }
}

CCAsync.prototype.waterfall = function(arr){
    if(!arr || arr.length == 0){
        console.warn('waterfall func arr is zero')
        return;
    }
    var array = null;
    if(arr instanceof Array){
        array = arr;
    } else {
        array = Array.prototype.slice.call(arguments);
    }
    for(var i in array){
        if(array[i] instanceof Function == false){
            console.warn('不是方法不能添加进回调')
            return;
        }
    }

    this.arrays = array;
    this.result = null;
    this.isOver = false
    this.waterIndex = -1;
    this._waterfallNext();
}

CCAsync.prototype._waterfallNext = function(err,result){
    this.waterIndex++;
    if(this.waterIndex >= this.arrays.length){
        return;
    }
    if(err){
        var fc = this.arrays.pop();
        fc(err);
        return
    }
    var func = this.arrays[this.waterIndex];
    if(this.waterIndex == 0){
        func(this._waterfallNext.bind(this));
    } else if(this.waterIndex == this.arrays.length-1){
        func(null,result);
    } else {
        func(result,this._waterfallNext.bind(this));
    }
}
window.CCAsync = CCAsync;
module.exports =CCAsync;